﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Utilities;
using System.IO;
using System.Data;
using StockCommon.data.TradeDetail;
using StockCommon.formula;

namespace StockCommon.data.bid5
{
    public class StockBid5DataProvider
    {
        protected static String getStringTemp()
        {
            String temp=@"D:\stockdata\bid5\{0}\{1}_{0}.xls";
            return temp;
        }
        protected static String getFileName(String code, DateTime date)
        {
            String fileName=String.Format(getStringTemp(), code, DateUtils.getPlanString(date));
            if (File.Exists(fileName))
                return fileName;
            return null;
        }
        public List<DateTime> getValidDate(String code)
        {
            String path=String.Format(@"D:\stockdata\bid5\{0}",code);
            String [] fs=Directory.GetFiles(path);
            List<DateTime>  result=new List<DateTime>();
                foreach(String fn in fs)
                {
                    if(fn.EndsWith(".xls")==false)
                        continue;

                    String f=Path.GetFileNameWithoutExtension(fn);
                    int pos=f.IndexOf("_");
                    if(pos<0)
                        continue;
                    f=f.Substring(0,pos);
                    DateTime dt=DateTime.ParseExact(f,"yyyyMMdd",null);
                    result.Add(dt);
                }
            return result;
        }

        public class BidEntry
        {
            public DateTime time { get;set;}
            //量,雖然是int 但是表格都是double
            public double value { get; set; }
        }
        public class BidSeries
        {
            public string type;
            public double price;
            public List<BidEntry> entries=new List<BidEntry>();
            public int order=0;
        }
        protected static Dictionary<String,object> ProcessBid5Stack(String fileName,DateTime date)
        {
            Dictionary<String, object> result = new Dictionary<string, object>();
            String sheetName = "Stack";
            System.Data.DataTable dataTable = ExcelHelper.GetDataTableFromExcelFile(fileName, ref sheetName);

            int rowsz = dataTable.Rows.Count;
            int ddetimeidx=dataTable.Columns.IndexOf("DDETime");
            int secondidx = dataTable.Columns.IndexOf("secondOfDay");
            int volumeidx=dataTable.Columns.IndexOf("volume");
            int totavolumelidx=dataTable.Columns.IndexOf("total volume");
            int priceidx=dataTable.Columns.IndexOf("price");
            int totalidx=dataTable.Columns.IndexOf("total");
            int totalbuyidx = dataTable.Columns.IndexOf("total buy");
            int totalsellidx = dataTable.Columns.IndexOf("total sell");

            List<StockMinuteDataSlice> tradeData = new List<StockMinuteDataSlice>();
            result.Add(StockBid5DataProvider.交易資料, tradeData);
            for (int i = 0; i < rowsz; i++)
            {
                DataRow row = dataTable.Rows[i];
                if (String.IsNullOrWhiteSpace(row[volumeidx].ToString()))
                    continue;
                StockMinuteDataSlice slice = new StockMinuteDataSlice();
                slice.time=Convert.ToDateTime(row[ddetimeidx]);
                slice.secondSpan = Convert.ToInt32(row[secondidx]);
                slice.單量= Convert.ToInt32(row[volumeidx]);
                slice.成交量 =Convert.ToInt32(row[totavolumelidx]);
                slice.成交價=Convert.ToDouble(row[priceidx]);
                slice.成交總額 = Convert.ToDouble(row[totalidx]);
                tradeData.Add(slice);
            }
            //處理開始.如果間隔太大..要有一個..start ? 似乎不用..應該是 
            //DDETime,total buy	total sell
            int cs=dataTable.Columns.Count;

            Dictionary<int, BidSeries> columnIdxToBs = new Dictionary<int, BidSeries>();
            List<int> __bsColumnIdx = new List<int>();
            for(int i=0;i<cs;i++)
            {
                String cname = dataTable.Columns[i].ColumnName;
                String[] ss=cname.Split(' ');
                if(ss.Length!=3)
                    continue;
                BidSeries bs = new BidSeries();
                String vs = ss[1].Replace("_", ".");
                bs.price = double.Parse(vs);
                if (ss[0].Equals("B") && ss[2].Equals("B"))
                {
                    bs.type = "buy";
                    __bsColumnIdx.Add(i);
                    columnIdxToBs.Add(i, bs);
                }
                 if (ss[0].Equals("S") && ss[2].Equals("S"))
                {
                    bs.type = "sell";
                    __bsColumnIdx.Add(i);
                    columnIdxToBs.Add(i, bs);
                }
                 
            }
            int[] bsColumnIdx = __bsColumnIdx.ToArray<int>();
            __bsColumnIdx.Clear();
            //---------------------------->
            BidSeries totalSellSeries = new BidSeries();
            totalSellSeries.type = "total Sell";
            BidSeries totalBuySeries = new BidSeries();
            totalBuySeries.type = "total Buy";

            result.Add(StockBid5DataProvider.總賣出委託Series, totalSellSeries);
            result.Add(StockBid5DataProvider.總買入委託Series, totalBuySeries);


            for (int i = 0; i < rowsz; i++)
            {
                DataRow row = dataTable.Rows[i];
                DateTime ddetime= Convert.ToDateTime(row[ddetimeidx]);
                String vs;
                double dv1 = Convert.ToDouble(row[totalsellidx].ToString());
                if (dv1 != 0)
                {
                    BidEntry be = new BidEntry();
                    be.time = ddetime;
                    be.value = dv1;
                    totalSellSeries.entries.Add(be);
                }
                double dv2 = Convert.ToDouble(row[totalbuyidx].ToString());                
                if (dv2 != 0)
                {
                    BidEntry be = new BidEntry();
                    be.time = ddetime;
                    be.value = dv2;
                    totalBuySeries.entries.Add(be);
                }
                //如果總買根總賣都=0 那根本不會有bid5 ,那就是.跳過
                if ((dv1 == 0) && (dv2 == 0))
                    continue;
                foreach (int ci in bsColumnIdx)
                {
                     vs= row[ci].ToString();
                    if (String.IsNullOrWhiteSpace(vs))
                        continue;
                    BidEntry be=new BidEntry();
                    be.time=ddetime;
                    be.value=Convert.ToDouble(vs);
                    BidSeries bs=columnIdxToBs[ci];
                    bs.entries.Add(be);
                }
            }
            //------------>SellSeries
            //------------>BuySeries

            List<BidSeries> sellSeries = new List<BidSeries>();
            List<BidSeries> buySeries = new List<BidSeries>();

            
            
            foreach (BidSeries bs in columnIdxToBs.Values)
            {
                if (bs.type == "buy")
                    buySeries.Add(bs);
                else
                    sellSeries.Add(bs);
            }
            columnIdxToBs.Clear();
            buySeries.Reverse();
            dataTable.Dispose();

            result.Add(StockBid5DataProvider.買價Series, buySeries);
            result.Add(StockBid5DataProvider.賣價Series, sellSeries);
            
            return result;
        }
        protected static int CompareBidEntryReverse(BidEntry o1,BidEntry o2)
        {
            return o2.value.CompareTo(o1.value);
        }
        public static Dictionary<String, object> getData(String code, DateTime date)
        {
            String fileName = getFileName(code, date);
            if (String.IsNullOrWhiteSpace(fileName))
                return null;
            Dictionary<String, object> result = ProcessBid5Stack(fileName, date);
            //前一日.
            double prev = StockDataModule.get前日收盤價(code, date);
            result.Add(StockBid5DataProvider.代號, code);
            result.Add(StockBid5DataProvider.名稱, StockManager.getStockName(code));
            result.Add(StockBid5DataProvider.前日收盤價, prev);

            double up=0;
            double down=0;
            StockPriceFormula.get股票UpDownStep(prev, out up, out down);
            result.Add(StockBid5DataProvider.漲停價, up);
            result.Add(StockBid5DataProvider.跌停價, down);
            return result;
        }
        public static String 交易資料 = "tradeData";
        public static String 跌停價 = "跌停價";
        public static String 漲停價 = "漲停價";
        public static String  前日收盤價="前日收盤價";
        public static String 代號 = "code";
        public static String  名稱 = "name";
        public static String 買價Series = "buySeries";
        public static String 賣價Series = "sellSeries";
        public static String 總賣出委託Series="totalSell";
        public static String 總買入委託Series="totalbuy";

    }
}
